home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / EDITORS / AE170.ZIP;1 / AE3.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-02-23  |  30.4 KB  |  741 lines

  1. UNIT AE3 ;
  2.  
  3. {$R-}
  4. {$B-}
  5. {$I-}
  6. {$S+}
  7. {$V-}
  8.  
  9. INTERFACE
  10.  
  11. USES Crt, Dos, AE0, AE1, AE2 ;
  12.  
  13. PROCEDURE EnterString (VAR S : STRING; Hist : HistPtr ; Prompt : STRING ;
  14.                        MaxLength : BYTE ; CapsLock : BOOLEAN ; AlphaOnly : BOOLEAN) ;
  15. PROCEDURE EnterWord (VAR W : WORD ; Prompt : STRING ; MinValue, MaxValue : WORD) ;
  16. PROCEDURE SaveFile (Wsnr : BYTE) ;
  17. FUNCTION GetKeyNr : WORD ;
  18. FUNCTION Answer (question : STRING) : BOOLEAN ;
  19. FUNCTION Choose (Choices, Prompt : STRING) : CHAR ;
  20. PROCEDURE DisplayInfo ;
  21.  
  22. IMPLEMENTATION
  23.  
  24. {-----------------------------------------------------------------------------}
  25. { Prompts the user to enter a string on the bottom line of the screen, with   }
  26. { maximum length <MaxLength>. Parameters CapsLock and AlphaOnly instruct the  }
  27. { procedure to convert lower case characters to upper case, and to accept     }
  28. { only alphanumeric characters, respectively. Pressing Escape will restore    }
  29. { the old value of S.                                                         }
  30. {-----------------------------------------------------------------------------}
  31.  
  32. PROCEDURE EnterString (VAR S : STRING; Hist : HistPtr ; Prompt : STRING ;
  33.                        MaxLength : BYTE ; CapsLock : BOOLEAN ; AlphaOnly : BOOLEAN) ;
  34.  
  35. VAR OldS : STRING ;
  36.     OldXpos, OldYpos : BYTE ;
  37.     OldCursorType : BYTE ;
  38.     i,j : BYTE ;
  39.     Key : WORD ;
  40.     Start, VisibleLength : BYTE ;
  41.     ShowOnScreen : BOOLEAN ;
  42.  
  43. BEGIN
  44. OldXpos := WHEREX ;
  45. OldYpos := WHEREY ;
  46. OldCursorType := GetCursor ;
  47. SetCursor (Config.Setup.CursorType) ;
  48. OldS := S ;
  49. { translate CR/LF pairs in string to CRLFalias ('Ÿ') }
  50. REPEAT i := POS (CR + LF, S) ;
  51.        IF i > 0
  52.           THEN BEGIN
  53.                S [i] := CRLFalias [1] ;
  54.                S [i + 1] := CRLFalias [2] ;
  55.                END ;
  56. UNTIL i = 0 ;
  57. Start := 1 ;
  58. VisibleLength := ColsOnScreen - LENGTH (Prompt) - 1 ;
  59. ShowOnScreen := (MacroStackPointer = Inactive) ;
  60. IF ShowOnScreen
  61.    THEN BEGIN
  62.         SetBottomLine (Prompt + COPY (S, Start, VisibleLength) ) ;
  63.         CursorTo (LENGTH (Prompt) + 1, 25) ;
  64.         END ;
  65. Key := GetKeyNr ;
  66. IF (Key < 256) OR (Key = CtrlReturnKey)
  67.    THEN S := '' ;
  68. i := 1 ;
  69. REPEAT CASE Key OF
  70.             264 {Bksp}    : IF i > 1
  71.                                THEN BEGIN
  72.                                     IF COPY (S, i - 1, 2) = CRLFalias
  73.                                        THEN BEGIN
  74.                                             DEC (i, 2) ;
  75.                                             DELETE (S, i, 2) ;
  76.                                             END
  77.                                        ELSE BEGIN
  78.                                             DEC (i) ;
  79.                                             DELETE (S, i, 1) ;
  80.                                             END ;
  81.                                     END
  82.                                ELSE WarningBeep ;
  83.             32..126       : IF LENGTH (S) < MaxLength
  84.                                THEN BEGIN
  85.                                     IF CapsLock
  86.                                        THEN INSERT (UPCASE (CHR (Key) ), S, i)
  87.                                        ELSE INSERT (CHR (Key), S, i) ;
  88.                                     INC (i) ;
  89.                                     END
  90.                                ELSE WarningBeep ;
  91.             1..31,
  92.             127..255      : IF (NOT AlphaOnly) AND (LENGTH (S) < MaxLength)
  93.                                THEN BEGIN
  94.                                     INSERT (CHR (Key), S, i) ;
  95.                                     INC (i) ;
  96.                                     END
  97.                                ELSE WarningBeep ;
  98.             CtrlReturnKey : IF (NOT AlphaOnly) AND (LENGTH (S) < (MaxLength - 1) )
  99.                                THEN BEGIN
  100.                                     INSERT (CRLFalias, S, i) ;
  101.                                     INC (i, 2)
  102.                                     END
  103.                                ELSE WarningBeep ;
  104.             327 {Home}    : i := 1 ;
  105.             335 {End}     : i := LENGTH (S) + 1 ;
  106.             331 {Left}    : IF i > 1
  107.                                THEN BEGIN
  108.                                     IF (COPY (S, i - 2, 2) = CRLFalias) AND (i > 2)
  109.                                        THEN DEC (i, 2)
  110.                                        ELSE DEC (i) ;
  111.                                     END ;
  112.             333 {Right}   : IF i <= LENGTH (S)
  113.                                THEN BEGIN
  114.                                     IF COPY (S, i, 2) = CRLFalias
  115.                                        THEN INC (i, 2)
  116.                                        ELSE INC (i) ;
  117.                                     END ;
  118.             371 {^Left}   : BEGIN
  119.                             IF i > 1
  120.                                THEN BEGIN
  121.                                     REPEAT DEC (i) ;
  122.                                     UNTIL (NOT (S [i] IN WordSeparators) ) OR
  123.                                           (i = 1) ;
  124.                                     WHILE (NOT (S [i - 1] IN WordSeparators) ) AND
  125.                                           (i > 1)
  126.                                           DO DEC (i) ;
  127.                                     END ;
  128.                             END ;
  129.             372 { ^Right} : BEGIN
  130.                             WHILE (NOT (S [i] IN WordSeparators) ) AND
  131.                                   (i <= LENGTH (S) )
  132.                                   DO INC (i) ;
  133.                             WHILE (S [i] IN WordSeparators) AND
  134.                                   (i <= LENGTH (S) )
  135.                                   DO INC (i) ;
  136.                             END ;
  137.             339 {Del}     : IF COPY (S, i, 2) = CRLFalias
  138.                                THEN DELETE (S, i, 2)
  139.                                ELSE DELETE (S, i, 1) ;
  140.             273 {Alt-W}   : BEGIN
  141.                             j := i ;
  142.                             WHILE (NOT (S [j] IN WordSeparators) ) AND
  143.                                   (j <= LENGTH (S) )
  144.                                   DO INC (j) ;
  145.                             WHILE (S [j] IN WordSeparators) AND
  146.                                   (j <= LENGTH (S) )
  147.                                   DO INC (j) ;
  148.                             DELETE (S, i, j-i) ;
  149.                             END ;
  150.             294 {Alt-L}   : BEGIN
  151.                             S := '' ;
  152.                             i := 1 ;
  153.                             END ;
  154.             328 { up },
  155.             336 { down }  : IF Hist = NIL
  156.                                THEN WarningBeep
  157.                                ELSE BEGIN
  158.                                     IF Hist^.Len > 0
  159.                                        THEN BEGIN
  160.                                             IF Key = 328 { up }
  161.                                                THEN S := PrevHistLine (Hist)
  162.                                                ELSE S := NextHistLine (Hist) ;
  163.                                             i := 1 ;
  164.                                             END ;
  165.                                     END ;
  166.             338 {Ins}     : Config.Setup.Insertmode := 
  167.                                 NOT Config.Setup.Insertmode ;
  168.             END ; { of case }
  169.        IF i > (Start + VisibleLength)
  170.           THEN Start := i - VisibleLength
  171.           ELSE BEGIN
  172.                IF Start > i
  173.                   THEN Start := i ;
  174.                END ;
  175.        IF ShowOnScreen
  176.           THEN BEGIN
  177.                SetBottomLine (Prompt + COPY (S, Start, VisibleLength) ) ;
  178.                CursorTo (LENGTH (Prompt) + 1 + i - Start, 25) ;
  179.                END ;
  180.        IF (Key <> ReturnKey) AND (Key <> EscapeKey) THEN Key := GetKeyNr ;
  181. UNTIL (Key = ReturnKey) OR (Key = EscapeKey) ;
  182. EscPressed := (Key = EscapeKey) ;
  183. IF EscPressed
  184.    THEN BEGIN
  185.         S := OldS ;
  186.         IF Hist <> NIL THEN Hist^.CurLine := 0 ;
  187.         END
  188.    ELSE BEGIN
  189.         IF (Hist <> NIL)
  190.            THEN IF (LENGTH(S) > 0)
  191.                 THEN AddToHistory (Hist, S)
  192.                 ELSE Hist^.CurLine := 0 ;
  193.         { replace CRLFalias in string with CR/LF pairs }
  194.         REPEAT i := POS (CRLFalias, S) ;
  195.                IF i > 0
  196.                   THEN BEGIN
  197.                        S [i] := CR ;
  198.                        S [i + 1] := LF ;
  199.                        END ;
  200.         UNTIL i = 0 ;
  201.         END ;
  202. IF ShowOnScreen
  203.    THEN SetBottomLine ('') ;
  204. CursorTo (OldXpos, OldYpos) ;
  205. SetCursor (OldCursorType) ;
  206. END ;
  207.  
  208. {-----------------------------------------------------------------------------}
  209. { Prompts the user to enter a numeric value. If a string is entered that can  }
  210. { not be interpreted as a numeric value, or if the value is not within the    }
  211. { limits MinValue..MaxValue, an error is given and the procedure is repeated. }
  212. { Pressing Escape will restore the old value of W.                            }
  213. {-----------------------------------------------------------------------------}
  214.  
  215. PROCEDURE EnterWord (VAR W : WORD ; Prompt : STRING ; MinValue, MaxValue : WORD) ;
  216.  
  217. VAR S : STRING ;
  218.     Code : INTEGER ;
  219.     OK : BOOLEAN ;
  220.  
  221. BEGIN
  222. STR (W, S) ;
  223. REPEAT EnterString (S, NIL, Prompt, 5, FALSE, TRUE) ;
  224.        VAL (S, W, Code) ;
  225.        IF Code <> 0 
  226.           THEN ErrorMessage (20)
  227.           ELSE BEGIN
  228.                IF W < MinValue
  229.                   THEN ErrorMessage (21) ;
  230.                IF W > MaxValue
  231.                   THEN ErrorMessage (22) ;
  232.                END ;
  233. UNTIL (Code = 0) AND (W >= MinValue) AND (W <= MaxValue) ;
  234. END ;
  235.  
  236. {-----------------------------------------------------------------------------}
  237. { Saves the file in workspace <Wsnr> to disk. If there is no name yet,        }
  238. { the user is prompted for one.                                               }
  239. {-----------------------------------------------------------------------------}
  240.  
  241. PROCEDURE SaveFile (Wsnr : BYTE) ;
  242.  
  243. VAR F : FILE ;
  244.     Counter : WORD ;
  245.     DotPos : BYTE ;
  246.     BAKfilename : PathStr ;
  247.     OldStatusLine : ScreenBlockPtr ;
  248.  
  249. BEGIN
  250. { save contents of statusline }
  251. SaveArea (1, LinesOnScreen, ColsOnScreen, LinesOnScreen, OldStatusLine) ;
  252. { make copy of current workspace equal to original }
  253. IF Wsnr = CurrentWsnr
  254.    THEN Workspace [CurrentWsnr] := CurrentWs ;
  255. WITH Workspace [Wsnr] DO
  256.      BEGIN
  257.      EscPressed := FALSE ;
  258.      IF LENGTH (Name) = 0
  259.         THEN BEGIN
  260.              EnterString (Name, NIL, 'Saving file. Filename: ', 79, TRUE, TRUE) ;
  261.              IF LENGTH (Name) = 0
  262.                 THEN EscPressed := TRUE
  263.                 ELSE IF Wildcarded (Name)
  264.                         THEN BEGIN
  265.                              ErrorMessage (16) ;
  266.                              EscPressed := TRUE ;
  267.                              END
  268.                         ELSE Name := FExpand (Name) ;
  269.              END ;
  270.      IF NOT EscPressed
  271.         THEN BEGIN
  272.              Message ('Saving file ' + Name) ;
  273.              IF (Config.Setup.MakeBAKfile) AND (Exists (Name) )
  274.                 THEN BEGIN
  275.                      { determine name of backup file }
  276.                      DotPos := POS ('.', Name) ;
  277.                      IF DotPos = 0
  278.                         THEN BAKfilename := Name + '.BAK'
  279.                         ELSE BAKfilename := COPY (Name, 1, DotPos) + 'BAK' ;
  280.                      { delete old backup file if present }
  281.                      IF Exists (BAKfilename)
  282.                         THEN BEGIN
  283.                              ASSIGN (F, BAKfilename) ;
  284.                              ERASE (F) ;
  285.                              END ;
  286.                      { rename file to backup file }
  287.                      ASSIGN (F, Name) ;
  288.                      RENAME (F, BAKfilename) ;
  289.                      END ;
  290.              ASSIGN (F, Name) ;
  291.              REWRITE (F, BufferSize) ;
  292.              CheckDiskError ;
  293.              IF DiskError = 0
  294.                 THEN BEGIN
  295.                      { save contents of buffer to file }
  296.                      BLOCKWRITE (F, Buffer^, 1) ;
  297.                      CheckDiskError ;
  298.                      CLOSE (F) ;
  299.                      IF DiskError = 0
  300.                         THEN { save was successful }
  301.                              ChangesMade := FALSE ;
  302.                      END ;
  303.              GETTIME (LastTimeSaved [1], LastTimeSaved [2],
  304.                       LastTimeSaved [3], LastTimeSaved [4]) ;
  305.              MessageRead := TRUE ;
  306.              END ;
  307.      END ; { of with }
  308. { restore status line }
  309. RestoreArea (1, LinesOnScreen, ColsOnScreen, LinesOnScreen, OldStatusLine) ;
  310. END ;
  311.  
  312. {-----------------------------------------------------------------------------}
  313. { Displays a table with the entire IBM character set, from which the user     }
  314. { can then make a choice, using the cursor and Return keys. Pressing Escape   }
  315. { will return a value of 279. Cursor shape and position and screen contents   }
  316. { are saved, and restored on exit.                                            }
  317. {-----------------------------------------------------------------------------}
  318.  
  319. FUNCTION GetKeyFromTable : WORD ;
  320.  
  321. VAR OldAttr, OldXpos, OldYpos, OldCursorType, KeyNr, Counter : BYTE ;
  322.     OldDisplayContents : ScreenBlockPtr ;
  323.     ScrEl : ScreenElement ;
  324.     SelectKey : WORD ;
  325.  
  326. BEGIN
  327. OldXpos := WHEREX ;
  328. OldYpos := WHEREY ;
  329. OldCursorType := GetCursor ;
  330. OldAttr := TextAttr ;
  331. TextAttr := ScreenColorArray [Config.Setup.ScreenColors].NormAttr ;
  332. SaveArea (7, 2, 74, 21, OldDisplayContents) ;
  333. SetCursor (Inactive) ;
  334. { put empty table on screen }
  335. PutFrame (7, 2, 74, 21, Quasi3DFrame) ;
  336. ClearArea (8, 3, 73, 20) ;
  337. ScrEl.Attribute := TextAttr ;
  338. { fill table }
  339. FOR Counter := 0 TO 255 DO
  340.     BEGIN
  341.     ScrEl.Contents := CHR (Counter) ;
  342.     DisplayPtr^ [4 + (Counter DIV 32) * 2, 9 + (Counter MOD 32) * 2] := WORD (ScrEl) ;
  343.     END ;
  344. KeyNr := 0 ;
  345. REPEAT GOTOXY (9, 20) ; WRITE ('ASCII value: ', KeyNr : 3) ;
  346.        { show selected character }
  347.        WITH ScreenColorArray [Config.Setup.ScreenColors] DO
  348.             ScrEl.Attribute := BlockAttr ;
  349.        ScrEl.Contents := CHR (KeyNr) ;
  350.        DisplayPtr^ [4 + (KeyNr DIV 32) * 2, 9 + (KeyNr MOD 32) * 2] := WORD (ScrEl) ;
  351.        { read a key from the keyboard }
  352.        SelectKey := ReadKeyNr ;
  353.        { hide previously selected character }
  354.        ScrEl.Attribute := TextAttr ;
  355.        ScrEl.Contents := CHR (KeyNr) ;
  356.        DisplayPtr^ [4 + (KeyNr DIV 32) * 2, 9 + (KeyNr MOD 32) * 2] := WORD (ScrEl) ;
  357.        CASE SelectKey OF
  358.             328       : { up     } DEC (KeyNr, 32) ;
  359.             336       : { down   } INC (KeyNr, 32) ;
  360.             331       : { left   } DEC (KeyNr) ;
  361.             333       : { right  } INC (KeyNr) ;
  362.             371       : { ^left  } DEC (KeyNr, 8) ;
  363.             372       : { ^right } INC (KeyNr, 8) ;
  364.             ReturnKey : ;
  365.             EscapeKey : ;
  366.             ELSE        WarningBeep ;
  367.             END ; { of case }
  368.        ScrEl.Attribute := TextAttr ;
  369.        ScrEl.Contents := CHR (KeyNr) ;
  370.        DisplayPtr^ [4 + (KeyNr DIV 32) * 2, 9 + (KeyNr MOD 32) * 2] := WORD (ScrEl) ;
  371. UNTIL (SelectKey = ReturnKey) OR (SelectKey = EscapeKey) ;
  372. RestoreArea (7, 2, 74, 21, OldDisplayContents) ;
  373. TextAttr := OldAttr ;
  374. GOTOXY (OldXpos, OldYpos) ;
  375. SetCursor (OldCursorType) ;
  376. IF SelectKey = EscapeKey
  377.    THEN GetKeyFromTable := 279 { alt-I }
  378.    ELSE GetKeyFromTable := KeyNr ;
  379. END ;
  380.  
  381. {-----------------------------------------------------------------------------}
  382. { Displays help screens containing the key definitions                        }
  383. { Cursor shape and position and screen contents are saved, and                }
  384. { restored on exit.                                                           }
  385. {-----------------------------------------------------------------------------}
  386.  
  387. PROCEDURE DisplayHelp ;
  388.  
  389. VAR OldDisplayContents : ScreenBlockPtr ;
  390.     OldXpos, OldYpos, OldCursorType : BYTE ;
  391.  
  392. BEGIN
  393. OldXpos := WHEREX ;
  394. OldYpos := WHEREY ;
  395. OldCursorType := GetCursor ;
  396. SetCursor (Inactive) ;
  397. SaveArea (1, 1, ColsOnScreen, LinesOnScreen, OldDisplayContents) ;
  398. ClearArea (1, 1, ColsOnScreen, NrOfTextLines) ;
  399. WRITELN ('      ⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø') ;
  400. WRITELN ('      ≥ NORMAL KEY  ≥ SHIFT+KEY                     ≥') ;
  401. WRITELN ('⁄ƒƒƒƒƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¥') ;
  402. WRITELN ('≥ F1  ≥ HELP        ≥ SETUP                         ≥') ;
  403. WRITELN ('≥ F2  ≥ SAVE FILE   ≥ WRITE TO FILE                 ≥') ;
  404. WRITELN ('≥ F3  ≥ LOAD FILE   ≥ INSERT FILE                   ≥') ;
  405. WRITELN ('≥ F4  ≥ FIND *      ≥ FIND & REPLACE *              ≥') ;
  406. WRITELN ('≥ F5  ≥ PUT MARK    ≥ ERASE MARK                    ≥') ;
  407. WRITELN ('≥ F6  ≥ CUT BLOCK   ≥ DELETE BLOCK                  ≥') ;
  408. WRITELN ('≥ F7  ≥ COPY BLOCK  ≥ COMPARE BLOCK TO PASTE BUFFER ≥') ;
  409. WRITELN ('≥ F8  ≥ PASTE BLOCK ≥ PRINT BLOCK                   ≥') ;
  410. WRITELN ('≥ F9  ≥ NEXT WINDOW ≥ PREVIOUS WINDOW               ≥') ;
  411. WRITELN ('≥ F10 ≥ DOS COMMAND ≥                               ≥') ;
  412. WRITELN ('¿ƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ') ;
  413. WRITELN ;
  414. WRITELN (' *: FIND/REPLACE OPTIONS') ;
  415. WRITELN ;
  416. WRITELN ('      I = IGNORE CASE') ;
  417. WRITELN ('      N = NO QUERY DURING REPLACE') ;
  418. WRITELN ('      R = REVERSE DIRECTION') ;
  419. WRITELN ('      W = SEARCH FOR WHOLE WORDS') ;
  420. Pause ;
  421. IF NOT EscPressed
  422.    THEN
  423.      BEGIN
  424.      ClearArea (1, 1, ColsOnScreen, NrOfTextLines) ;
  425.      WRITELN ('⁄ƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø') ;
  426.      WRITELN ('≥ ALT+KEY ≥ ACTION                     ≥') ;
  427.      WRITELN ('√ƒƒƒƒƒƒƒƒƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¥') ;
  428.      WRITELN ('≥ 1..9,0  ≥ REPLAY MACRO NR 1..9,10    ≥') ;
  429.      WRITELN ('≥ A       ≥ SWITCH TO WINDOW A         ≥') ;
  430.      WRITELN ('≥ C       ≥ CENTER LINE                ≥') ;
  431.      WRITELN ('≥ D       ≥ DEFINE KEYBOARD MACRO      ≥') ;
  432.      WRITELN ('≥ E       ≥ EJECT PRINTER PAGE         ≥') ;
  433.      WRITELN ('≥ F       ≥ FORMAT PARAGRAPH           ≥') ;
  434.      WRITELN ('≥ G       ≥ GET SAVED POSITION         ≥') ;
  435.      WRITELN ('≥ I       ≥ IBM CHAR.SET (ASCII TABLE) ≥') ;
  436.      WRITELN ('≥ J       ≥ JUSTIFY LINE TO THE RIGHT  ≥') ;
  437.      WRITELN ('≥ L       ≥ DELETE LINE                ≥') ;
  438.      WRITELN ('≥ M       ≥ MATCH BRACKETS ({[<>]})    ≥') ;
  439.      WRITELN ('≥ N       ≥ NEW (CLEAR BUFFER)         ≥') ;
  440.      WRITELN ('≥ P       ≥ PRINT ENTIRE FILE          ≥') ;
  441.      WRITELN ('≥ Q       ≥ DISPLAY EDITOR STATUS      ≥') ;
  442.      WRITELN ('≥ R       ≥ REPEAT LAST FIND/REPLACE   ≥') ;
  443.      WRITELN ('≥ S       ≥ SAVE POSITION              ≥') ;
  444.      WRITELN ('≥ T       ≥ TOGGLE UPPER/LOWERCASE     ≥') ;
  445.      WRITELN ('≥ U       ≥ CONVERT TO UPPERCASE       ≥') ;
  446.      WRITELN ('≥ W       ≥ DELETE WORD FORWARD        ≥') ;
  447.      WRITELN ('≥ X       ≥ EXIT PROGRAM               ≥') ;
  448.      WRITELN ('¿ƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ') ;
  449.      Pause ;
  450.      END ; { of if }
  451. IF NOT EscPressed
  452.    THEN
  453.      BEGIN
  454.      ClearArea (1, 1, ColsOnScreen, NrOfTextLines) ;
  455.      WRITELN ('            ⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø') ;
  456.      WRITELN ('            ≥ NORMAL KEY         ≥ CONTROL+KEY     ≥') ;
  457.      WRITELN ('⁄ƒƒƒƒƒƒƒƒƒƒƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¥') ;
  458.      WRITELN ('≥ ƒ        ≥ PREVIOUS CHARACTER ≥ PREVIOUS WORD   ≥') ;
  459.      WRITELN ('≥ ƒ        ≥ NEXT CHARACTER     ≥ NEXT WORD       ≥') ;
  460.      WRITELN ('≥          ≥ PREVIOUS LINE      ≥                 ≥') ;
  461.      WRITELN ('≥          ≥ NEXT LINE          ≥                 ≥') ;
  462.      WRITELN ('≥ Home      ≥ BEGIN OF LINE      ≥ BEGIN OF SCREEN ≥') ;
  463.      WRITELN ('≥ End       ≥ END OF LINE        ≥ END OF SCREEN   ≥') ;
  464.      WRITELN ('≥ Page Up   ≥ PREVIOUS SCREEN    ≥ BEGIN OF TEXT   ≥') ;
  465.      WRITELN ('≥ Page Dn   ≥ NEXT SCREEN        ≥ END OF TEXT     ≥') ;
  466.      WRITELN ('¿ƒƒƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ') ;
  467.      WRITELN ;
  468.      WRITELN ('⁄ƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø') ;
  469.      WRITELN ('≥ Insert    ≥ TOGGLE INSERT/OVERWRITE MODE  ≥') ;
  470.      WRITELN ('≥ Delete    ≥ REMOVE CHARACTER UNDER CURSOR ≥') ;
  471.      WRITELN ('≥ Backspace ≥ REMOVE PREVIOUS CHARACTER     ≥') ;
  472.      WRITELN ('≥ Escape    ≥ ABORT OPERATION/ERASE MARK    ≥') ;
  473.      WRITELN ('¿ƒƒƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ') ;
  474.      Pause ;
  475. END ; { of if }
  476. RestoreArea (1, 1, ColsOnScreen, LinesOnScreen, OldDisplayContents) ;
  477. GOTOXY (OldXpos, OldYpos) ;
  478. SetCursor (OldCursorType) ;
  479. END ;
  480.  
  481. {-----------------------------------------------------------------------------}
  482. { Returns a key number, read from a macro if one is running, or from the      }
  483. { keyboard otherwise. The procedure takes care of displaying ASCII tables,    }
  484. { help screens and of storing the number of the key in the macro space        }
  485. { if a macro is being defined.                                                }
  486. {-----------------------------------------------------------------------------}
  487.  
  488. FUNCTION GetKeyNr : WORD ;
  489.  
  490. VAR KeyNr : WORD ;
  491.     Hrs, Mins, Secs, Sec100s, TimePassed : WORD ;
  492.     WsNr : BYTE ;
  493.  
  494. BEGIN
  495. IF MacroStackpointer <> Inactive
  496.    THEN 
  497.      BEGIN
  498.      CheckEsc ;
  499.      IF EscPressed
  500.         THEN BEGIN
  501.              { macro execution interrupted }
  502.              MacroStackpointer := Inactive ;
  503.              ErrorMessage (18) ;
  504.              KeyNr := EscapeKey ;
  505.              END
  506.         ELSE { get keynumber from macro }
  507.              WITH Config DO
  508.                   BEGIN
  509.                   Keynr := Macro.Contents [MacroStack [MacroStackpointer].Macronr,
  510.                                MacroStack [MacroStackpointer].Index] ;
  511.                   REPEAT { set Index to next keynumber in macro sequence }
  512.                          INC (MacroStack [MacroStackpointer].Index) ;
  513.                          IF MacroStack [MacroStackpointer].Index >
  514.                             Macro.LENGTH [MacroStack [MacroStackpointer].Macronr]
  515.                             THEN BEGIN
  516.                                  { macro finished, decrease stackpointer }
  517.                                  DEC (MacroStackpointer) ;
  518.                                  END ;
  519.                   UNTIL (MacroStackpointer = Inactive) OR
  520.                         (MacroStack [MacroStackpointer].Index <=
  521.                         Macro.LENGTH [MacroStack [MacroStackpointer].Macronr]) ;
  522.                   END ; { of with }
  523.         END
  524.    ELSE BEGIN
  525.         { get keynumber from keyboard }
  526.         REPEAT GETTIME (Hrs, Mins, Secs, Sec100s) ;
  527.               FOR WsNr := 1 TO NrOfWorkspaces DO
  528.                   WITH Workspace [WsNr] DO
  529.                        BEGIN
  530.                        { calculate time since last save of file in Workspace }
  531.                        IF LastTimeSaved [1] > Hrs
  532.                           THEN TimePassed := 60 * (24 + Hrs - LastTimeSaved [1])
  533.                           ELSE TimePassed := 60 * (Hrs - LastTimeSaved [1]) ;
  534.                        IF LastTimeSaved [2] > Mins
  535.                           THEN DEC (TimePassed, LastTimeSaved [2] - Mins)
  536.                           ELSE INC (TimePassed, Mins - LastTimeSaved [2]) ;
  537.                        IF LastTimeSaved [3] > Secs
  538.                           THEN DEC (TimePassed) ;
  539.                        IF (Config.Setup.SaveInterval <> Inactive) AND
  540.                           (TimePassed >= Config.Setup.SaveInterval) AND
  541.                           ChangesMade AND
  542.                           (LENGTH (Name) <> 0)
  543.                           THEN SaveFile (Wsnr) ;
  544.                        END ; { of with }
  545.         UNTIL KEYPRESSED ;
  546.         REPEAT KeyNr := ReadKeyNr ;
  547.                IF KeyNr = 315 { F1 } THEN DisplayHelp ;
  548.                IF KeyNr = 279 { alt-I } THEN KeyNr := GetKeyFromTable ;
  549.         UNTIL (KeyNr <> 315) AND (KeyNr <> 279) ;
  550.         IF Config.Setup.Keyclick
  551.            THEN BEGIN
  552.                 SOUND (440) ;
  553.                 DELAY (2) ;
  554.                 NOSOUND ;
  555.                 END ;
  556.         IF (MacroDefining <> Inactive) AND (KeyNr <> 288 { alt-D })
  557.            THEN BEGIN
  558.                 IF Config.Macro.LENGTH [MacroDefining] = MaxMacroLength
  559.                    THEN BEGIN
  560.                         { macro too long }
  561.                         ErrorMessage (6) ;
  562.                         MacroDefining := Inactive ;
  563.                         END
  564.                    ELSE BEGIN
  565.                         { add keynumber to macro }
  566.                         INC (Config.Macro.LENGTH [MacroDefining]) ;
  567.                         Config.Macro.Contents [MacroDefining,
  568.                                  Config.Macro.LENGTH [MacroDefining]] := KeyNr ;
  569.                         END ;
  570.                 END ;
  571.         END ; { of if }
  572. GetKeyNr := KeyNr ;
  573. MessageRead := TRUE ;
  574. END ;
  575.  
  576. {-----------------------------------------------------------------------------}
  577. { Puts a question on the bottom screen line and then waits until the Y, N or  }
  578. { Escape key is pressed. The Y key produces a True result, the N and Escape   }
  579. { a False function result.                                                    }
  580. {-----------------------------------------------------------------------------}
  581.  
  582. FUNCTION Answer (Question : STRING) : BOOLEAN ;
  583.  
  584. VAR Key : WORD ;
  585.     OldX, OldY, OldCursorType : BYTE ;
  586.  
  587. BEGIN
  588. OldX := WHEREX ;
  589. OldY := WHEREY ;
  590. OldCursorType := GetCursor ;
  591. Message (Question + ' (Y/N) ') ;
  592. CursorTo (LENGTH (Question) + 8, LinesOnScreen) ;
  593. SetCursor (Config.Setup.CursorType) ;
  594. REPEAT Key := GetKeyNr
  595. UNTIL (Key IN [78, 89, 110, 121]) OR
  596.       (Key = EscapeKey) ;
  597. Answer := (Key = 89) OR (Key = 121) ;
  598. EscPressed := (Key = EscapeKey) ;
  599. CursorTo (OldX, OldY) ;
  600. SetCursor (OldCursorType) ;
  601. END ;
  602.  
  603. {-----------------------------------------------------------------------------}
  604. { Displays the Choices string on the bottom screen line, and waits for the    }
  605. { user to make a choice, which is made by pressing a letter key which,        }
  606. { converted to upper case, also occurs in the string. This key is then        }
  607. { returned as the function result. Exit by pressing Escape is also possible.  }
  608. {-----------------------------------------------------------------------------}
  609.  
  610. FUNCTION Choose (Choices, Prompt : STRING) : CHAR ;
  611.  
  612. VAR BottomLine : STRING ;
  613.     Key : WORD ;
  614.     Choice : CHAR ;
  615.     Ready : BOOLEAN ;
  616.     P, Col : BYTE ;
  617.     ScrEl : ScreenElement ;
  618.     ScrElPtr : ScreenElementPtr ;
  619.     OldCursorType : BYTE ;
  620.     ShowOnScreen : BOOLEAN ;
  621.  
  622. BEGIN
  623. OldCursorType := GetCursor ;
  624. SetCursor (Inactive) ;
  625. ScrEl.Attribute := ScreenColorArray [Config.Setup.ScreenColors].StatusCursorAttr ;
  626. Ready := FALSE ;
  627. BottomLine := Prompt + Choices ;
  628. P := LENGTH (Prompt) + 1 ;
  629. ShowOnScreen := (MacroStackPointer = Inactive) ;
  630. REPEAT IF ShowOnScreen
  631.           THEN BEGIN
  632.                SetBottomLine (BottomLine) ;
  633.                Col := P ;
  634.                { write selected choice with different screen attribute }
  635.                ScrElPtr := ScreenElementPtr (StatusLinePtr) ;
  636.                INC(ScrElPtr.OFS,2*(Col-1)) ;
  637.                WHILE (BottomLine[Col] <> ' ') AND
  638.                      (Col <= LENGTH(BottomLine)) DO
  639.                      BEGIN
  640.                      ScrEl.Contents := BottomLine [Col] ;
  641.                      ScrElPtr.Ref^ := ScrEl ;
  642.                      INC (Col) ;
  643.                      INC(ScrElPtr.OFS,2) ;
  644.                      END ;
  645.        END ;
  646.        Key := GetKeyNr ;
  647.        CASE Key OF
  648.          331,328    : { left, up }
  649.                       BEGIN
  650.                       REPEAT IF P = LENGTH (Prompt) + 1
  651.                                 THEN P := LENGTH(BottomLine)
  652.                                 ELSE DEC (P) ;
  653.                       UNTIL ((BottomLine[P-1] = ' ') AND (BottomLine[P] <> ' '))
  654.                             OR (P = LENGTH (Prompt) + 1) ;
  655.                       END ;
  656.          32,333,336 : { space, right, down }
  657.                       BEGIN
  658.                       REPEAT IF P = LENGTH(BottomLine)
  659.                                 THEN P := LENGTH (Prompt) + 1
  660.                                 ELSE INC (P) ;
  661.                       UNTIL ((BottomLine[P-1] = ' ') AND (BottomLine[P] <> ' '))
  662.                             OR (P = LENGTH (Prompt) + 1) ;
  663.                       END ;
  664.          64..255    : BEGIN
  665.                       IF POS (UPCASE (CHR (Key)), Choices) <> 0
  666.                          THEN BEGIN
  667.                               P := POS (UPCASE (CHR (Key)), Choices) +
  668.                                    Length (prompt) ;
  669.                               Ready := TRUE ;
  670.                               END
  671.                          ELSE WarningBeep ;
  672.                       END ;
  673.          ReturnKey, EscapeKey : Ready := TRUE ;
  674.          END ; { of case }
  675. UNTIL Ready ;
  676. EscPressed := (Key = EscapeKey) ;
  677. IF EscPressed
  678.    THEN Choose := ' '
  679.    ELSE BEGIN
  680.         WHILE (UPCASE(BottomLine[P]) <> BottomLine[P]) DO
  681.               INC(P) ;
  682.         Choose := BottomLine[P] ;
  683.         END ;
  684. Message ('') ;
  685. SetCursor (OldCursorType) ;
  686. END ;
  687.  
  688. {-----------------------------------------------------------------------------}
  689. { Displays screen with info about loaded files.                               }
  690. { Cursor shape and position and screen contents are saved, and                }
  691. { restored on exit.                                                           }
  692. {-----------------------------------------------------------------------------}
  693.  
  694. PROCEDURE DisplayInfo ;
  695.  
  696. VAR OldDisplayContents : ScreenBlockPtr ;
  697.     OldXpos, OldYpos, OldCursorType : BYTE ;
  698.     Counter : WORD ;
  699.  
  700. BEGIN
  701. OldXpos := WHEREX ;
  702. OldYpos := WHEREY ;
  703. OldCursorType := GetCursor ;
  704. SaveArea (1, 1, ColsOnScreen, LinesOnScreen, OldDisplayContents) ;
  705. ClearArea (1, 1, ColsOnScreen, NrOfTextLines) ;
  706. WRITELN ('EDITOR STATUS') ;
  707. FOR Counter := 1 TO NrOfWorkSpaces DO
  708.     WITH Workspace [Counter] DO
  709.          BEGIN
  710.          WRITELN ;
  711.          WRITE ('Window ', CHR (64 + Counter) ) ;
  712.          IF Name <> ''
  713.             THEN BEGIN
  714.                  GOTOXY (15,WhereY) ;
  715.                  WRITELN ('File: ', Name) ;
  716.                  END ;
  717.          IF BufferSize > 1
  718.             THEN BEGIN
  719.                  GOTOXY (15,WhereY) ;
  720.                  WRITELN ('Contains ', BufferSize, ' bytes.') ;
  721.                  GOTOXY (15,WhereY) ;
  722.                  WRITELN ('Cursor at offset ', Curpos.Index - 1,
  723.                           ', character is ASCII ', ORD (Buffer^ [CurPos.Index]),
  724.                           '.') ;
  725.                  END
  726.             ELSE BEGIN
  727.                  GOTOXY (15,WhereY) ;
  728.                  WRITELN ('Empty') ;
  729.                  END ;
  730.           END ;
  731. SetCursor (Inactive) ;
  732. Pause ;
  733. RestoreArea (1, 1, ColsOnScreen, LinesOnScreen, OldDisplayContents) ;
  734. GOTOXY (OldXpos, OldYpos) ;
  735. SetCursor (OldCursorType) ;
  736. END ;
  737.  
  738. {-----------------------------------------------------------------------------}
  739.  
  740. END.
  741.